{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:05.035457400Z",
     "start_time": "2023-12-10T02:11:05.017473300Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "data": {
      "text/plain": "   customerID  gender  SeniorCitizen Partner Dependents  tenure PhoneService  \\\n0  7590-VHVEG  Female              0     Yes         No       1           No   \n1  5575-GNVDE    Male              0      No         No      34          Yes   \n2  3668-QPYBK    Male              0      No         No       2          Yes   \n3  7795-CFOCW    Male              0      No         No      45           No   \n4  9237-HQITU  Female              0      No         No       2          Yes   \n\n      MultipleLines InternetService OnlineSecurity  ... DeviceProtection  \\\n0  No phone service             DSL             No  ...               No   \n1                No             DSL            Yes  ...              Yes   \n2                No             DSL            Yes  ...               No   \n3  No phone service             DSL            Yes  ...              Yes   \n4                No     Fiber optic             No  ...               No   \n\n  TechSupport StreamingTV StreamingMovies        Contract PaperlessBilling  \\\n0          No          No              No  Month-to-month              Yes   \n1          No          No              No        One year               No   \n2          No          No              No  Month-to-month              Yes   \n3         Yes          No              No        One year               No   \n4          No          No              No  Month-to-month              Yes   \n\n               PaymentMethod MonthlyCharges  TotalCharges Churn  \n0           Electronic check          29.85         29.85    No  \n1               Mailed check          56.95        1889.5    No  \n2               Mailed check          53.85        108.15   Yes  \n3  Bank transfer (automatic)          42.30       1840.75    No  \n4           Electronic check          70.70        151.65   Yes  \n\n[5 rows x 21 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>customerID</th>\n      <th>gender</th>\n      <th>SeniorCitizen</th>\n      <th>Partner</th>\n      <th>Dependents</th>\n      <th>tenure</th>\n      <th>PhoneService</th>\n      <th>MultipleLines</th>\n      <th>InternetService</th>\n      <th>OnlineSecurity</th>\n      <th>...</th>\n      <th>DeviceProtection</th>\n      <th>TechSupport</th>\n      <th>StreamingTV</th>\n      <th>StreamingMovies</th>\n      <th>Contract</th>\n      <th>PaperlessBilling</th>\n      <th>PaymentMethod</th>\n      <th>MonthlyCharges</th>\n      <th>TotalCharges</th>\n      <th>Churn</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>7590-VHVEG</td>\n      <td>Female</td>\n      <td>0</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>1</td>\n      <td>No</td>\n      <td>No phone service</td>\n      <td>DSL</td>\n      <td>No</td>\n      <td>...</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>Month-to-month</td>\n      <td>Yes</td>\n      <td>Electronic check</td>\n      <td>29.85</td>\n      <td>29.85</td>\n      <td>No</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>5575-GNVDE</td>\n      <td>Male</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>34</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>DSL</td>\n      <td>Yes</td>\n      <td>...</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>One year</td>\n      <td>No</td>\n      <td>Mailed check</td>\n      <td>56.95</td>\n      <td>1889.5</td>\n      <td>No</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>3668-QPYBK</td>\n      <td>Male</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>2</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>DSL</td>\n      <td>Yes</td>\n      <td>...</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>Month-to-month</td>\n      <td>Yes</td>\n      <td>Mailed check</td>\n      <td>53.85</td>\n      <td>108.15</td>\n      <td>Yes</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>7795-CFOCW</td>\n      <td>Male</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>45</td>\n      <td>No</td>\n      <td>No phone service</td>\n      <td>DSL</td>\n      <td>Yes</td>\n      <td>...</td>\n      <td>Yes</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>No</td>\n      <td>One year</td>\n      <td>No</td>\n      <td>Bank transfer (automatic)</td>\n      <td>42.30</td>\n      <td>1840.75</td>\n      <td>No</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>9237-HQITU</td>\n      <td>Female</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>2</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>Fiber optic</td>\n      <td>No</td>\n      <td>...</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>Month-to-month</td>\n      <td>Yes</td>\n      <td>Electronic check</td>\n      <td>70.70</td>\n      <td>151.65</td>\n      <td>Yes</td>\n    </tr>\n  </tbody>\n</table>\n<p>5 rows × 21 columns</p>\n</div>"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df =pd.read_csv(\"F:/机器学习数据集/电信客户流失数据/WA_Fn-UseC_-Telco-Customer-Churn.csv\")\n",
    "df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:05.836219900Z",
     "start_time": "2023-12-10T02:11:05.761199900Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "data": {
      "text/plain": "customerID           object\ngender               object\nSeniorCitizen         int64\nPartner              object\nDependents           object\ntenure                int64\nPhoneService         object\nMultipleLines        object\nInternetService      object\nOnlineSecurity       object\nOnlineBackup         object\nDeviceProtection     object\nTechSupport          object\nStreamingTV          object\nStreamingMovies      object\nContract             object\nPaperlessBilling     object\nPaymentMethod        object\nMonthlyCharges      float64\nTotalCharges         object\nChurn                object\ndtype: object"
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.dtypes"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:06.682295700Z",
     "start_time": "2023-12-10T02:11:06.656320800Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [
    {
     "data": {
      "text/plain": "customerID          0\ngender              0\nSeniorCitizen       0\nPartner             0\nDependents          0\ntenure              0\nPhoneService        0\nMultipleLines       0\nInternetService     0\nOnlineSecurity      0\nOnlineBackup        0\nDeviceProtection    0\nTechSupport         0\nStreamingTV         0\nStreamingMovies     0\nContract            0\nPaperlessBilling    0\nPaymentMethod       0\nMonthlyCharges      0\nTotalCharges        0\nChurn               0\ndtype: int64"
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:07.796860900Z",
     "start_time": "2023-12-10T02:11:07.780836Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "data": {
      "text/plain": "   customerID  gender  SeniorCitizen Partner Dependents  tenure PhoneService  \\\n0  7590-VHVEG  Female              0     Yes         No       1           No   \n1  5575-GNVDE    Male              0      No         No      34          Yes   \n2  3668-QPYBK    Male              0      No         No       2          Yes   \n3  7795-CFOCW    Male              0      No         No      45           No   \n4  9237-HQITU  Female              0      No         No       2          Yes   \n\n      MultipleLines InternetService OnlineSecurity  ... DeviceProtection  \\\n0  No phone service             DSL             No  ...               No   \n1                No             DSL            Yes  ...              Yes   \n2                No             DSL            Yes  ...               No   \n3  No phone service             DSL            Yes  ...              Yes   \n4                No     Fiber optic             No  ...               No   \n\n  TechSupport StreamingTV StreamingMovies        Contract PaperlessBilling  \\\n0          No          No              No  Month-to-month              Yes   \n1          No          No              No        One year               No   \n2          No          No              No  Month-to-month              Yes   \n3         Yes          No              No        One year               No   \n4          No          No              No  Month-to-month              Yes   \n\n               PaymentMethod MonthlyCharges  TotalCharges Churn  \n0           Electronic check          29.85         29.85     0  \n1               Mailed check          56.95        1889.5     0  \n2               Mailed check          53.85        108.15     1  \n3  Bank transfer (automatic)          42.30       1840.75     0  \n4           Electronic check          70.70        151.65     1  \n\n[5 rows x 21 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>customerID</th>\n      <th>gender</th>\n      <th>SeniorCitizen</th>\n      <th>Partner</th>\n      <th>Dependents</th>\n      <th>tenure</th>\n      <th>PhoneService</th>\n      <th>MultipleLines</th>\n      <th>InternetService</th>\n      <th>OnlineSecurity</th>\n      <th>...</th>\n      <th>DeviceProtection</th>\n      <th>TechSupport</th>\n      <th>StreamingTV</th>\n      <th>StreamingMovies</th>\n      <th>Contract</th>\n      <th>PaperlessBilling</th>\n      <th>PaymentMethod</th>\n      <th>MonthlyCharges</th>\n      <th>TotalCharges</th>\n      <th>Churn</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>7590-VHVEG</td>\n      <td>Female</td>\n      <td>0</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>1</td>\n      <td>No</td>\n      <td>No phone service</td>\n      <td>DSL</td>\n      <td>No</td>\n      <td>...</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>Month-to-month</td>\n      <td>Yes</td>\n      <td>Electronic check</td>\n      <td>29.85</td>\n      <td>29.85</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>5575-GNVDE</td>\n      <td>Male</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>34</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>DSL</td>\n      <td>Yes</td>\n      <td>...</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>One year</td>\n      <td>No</td>\n      <td>Mailed check</td>\n      <td>56.95</td>\n      <td>1889.5</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>3668-QPYBK</td>\n      <td>Male</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>2</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>DSL</td>\n      <td>Yes</td>\n      <td>...</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>Month-to-month</td>\n      <td>Yes</td>\n      <td>Mailed check</td>\n      <td>53.85</td>\n      <td>108.15</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>7795-CFOCW</td>\n      <td>Male</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>45</td>\n      <td>No</td>\n      <td>No phone service</td>\n      <td>DSL</td>\n      <td>Yes</td>\n      <td>...</td>\n      <td>Yes</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>No</td>\n      <td>One year</td>\n      <td>No</td>\n      <td>Bank transfer (automatic)</td>\n      <td>42.30</td>\n      <td>1840.75</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>9237-HQITU</td>\n      <td>Female</td>\n      <td>0</td>\n      <td>No</td>\n      <td>No</td>\n      <td>2</td>\n      <td>Yes</td>\n      <td>No</td>\n      <td>Fiber optic</td>\n      <td>No</td>\n      <td>...</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>No</td>\n      <td>Month-to-month</td>\n      <td>Yes</td>\n      <td>Electronic check</td>\n      <td>70.70</td>\n      <td>151.65</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n<p>5 rows × 21 columns</p>\n</div>"
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.Churn = (df.Churn=='Yes').astype(int)\n",
    "df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:14.198648100Z",
     "start_time": "2023-12-10T02:11:14.157650700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [
    {
     "data": {
      "text/plain": "0    5174\n1    1869\nName: Churn, dtype: int64"
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.Churn.value_counts()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:37.196564100Z",
     "start_time": "2023-12-10T02:11:37.129561700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "data": {
      "text/plain": "dtype('float64')"
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.TotalCharges = pd.to_numeric(df.TotalCharges,errors='coerce')\n",
    "df.TotalCharges = df.TotalCharges.fillna(0)\n",
    "df.TotalCharges.dtypes"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:11:43.475042800Z",
     "start_time": "2023-12-10T02:11:43.460103200Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "data": {
      "text/plain": "   customerid  gender  seniorcitizen partner dependents  tenure phoneservice  \\\n0  7590-vhveg  female              0     yes         no       1           no   \n1  5575-gnvde    male              0      no         no      34          yes   \n2  3668-qpybk    male              0      no         no       2          yes   \n3  7795-cfocw    male              0      no         no      45           no   \n4  9237-hqitu  female              0      no         no       2          yes   \n\n      multiplelines internetservice onlinesecurity  ... deviceprotection  \\\n0  no_phone_service             dsl             no  ...               no   \n1                no             dsl            yes  ...              yes   \n2                no             dsl            yes  ...               no   \n3  no_phone_service             dsl            yes  ...              yes   \n4                no     fiber_optic             no  ...               no   \n\n  techsupport streamingtv streamingmovies        contract paperlessbilling  \\\n0          no          no              no  month-to-month              yes   \n1          no          no              no        one_year               no   \n2          no          no              no  month-to-month              yes   \n3         yes          no              no        one_year               no   \n4          no          no              no  month-to-month              yes   \n\n               paymentmethod monthlycharges  totalcharges  churn  \n0           electronic_check          29.85         29.85      0  \n1               mailed_check          56.95       1889.50      0  \n2               mailed_check          53.85        108.15      1  \n3  bank_transfer_(automatic)          42.30       1840.75      0  \n4           electronic_check          70.70        151.65      1  \n\n[5 rows x 21 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>customerid</th>\n      <th>gender</th>\n      <th>seniorcitizen</th>\n      <th>partner</th>\n      <th>dependents</th>\n      <th>tenure</th>\n      <th>phoneservice</th>\n      <th>multiplelines</th>\n      <th>internetservice</th>\n      <th>onlinesecurity</th>\n      <th>...</th>\n      <th>deviceprotection</th>\n      <th>techsupport</th>\n      <th>streamingtv</th>\n      <th>streamingmovies</th>\n      <th>contract</th>\n      <th>paperlessbilling</th>\n      <th>paymentmethod</th>\n      <th>monthlycharges</th>\n      <th>totalcharges</th>\n      <th>churn</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>7590-vhveg</td>\n      <td>female</td>\n      <td>0</td>\n      <td>yes</td>\n      <td>no</td>\n      <td>1</td>\n      <td>no</td>\n      <td>no_phone_service</td>\n      <td>dsl</td>\n      <td>no</td>\n      <td>...</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>month-to-month</td>\n      <td>yes</td>\n      <td>electronic_check</td>\n      <td>29.85</td>\n      <td>29.85</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>5575-gnvde</td>\n      <td>male</td>\n      <td>0</td>\n      <td>no</td>\n      <td>no</td>\n      <td>34</td>\n      <td>yes</td>\n      <td>no</td>\n      <td>dsl</td>\n      <td>yes</td>\n      <td>...</td>\n      <td>yes</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>one_year</td>\n      <td>no</td>\n      <td>mailed_check</td>\n      <td>56.95</td>\n      <td>1889.50</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>3668-qpybk</td>\n      <td>male</td>\n      <td>0</td>\n      <td>no</td>\n      <td>no</td>\n      <td>2</td>\n      <td>yes</td>\n      <td>no</td>\n      <td>dsl</td>\n      <td>yes</td>\n      <td>...</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>month-to-month</td>\n      <td>yes</td>\n      <td>mailed_check</td>\n      <td>53.85</td>\n      <td>108.15</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>7795-cfocw</td>\n      <td>male</td>\n      <td>0</td>\n      <td>no</td>\n      <td>no</td>\n      <td>45</td>\n      <td>no</td>\n      <td>no_phone_service</td>\n      <td>dsl</td>\n      <td>yes</td>\n      <td>...</td>\n      <td>yes</td>\n      <td>yes</td>\n      <td>no</td>\n      <td>no</td>\n      <td>one_year</td>\n      <td>no</td>\n      <td>bank_transfer_(automatic)</td>\n      <td>42.30</td>\n      <td>1840.75</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>9237-hqitu</td>\n      <td>female</td>\n      <td>0</td>\n      <td>no</td>\n      <td>no</td>\n      <td>2</td>\n      <td>yes</td>\n      <td>no</td>\n      <td>fiber_optic</td>\n      <td>no</td>\n      <td>...</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>no</td>\n      <td>month-to-month</td>\n      <td>yes</td>\n      <td>electronic_check</td>\n      <td>70.70</td>\n      <td>151.65</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n<p>5 rows × 21 columns</p>\n</div>"
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns = df.columns.str.lower().str.replace(\" \",\"_\")\n",
    "str_cols = list(df.dtypes[df.dtypes=='object'].index)\n",
    "for col in str_cols:\n",
    "    df[col] = df[col].str.lower().str.replace(\" \",\"_\")\n",
    "df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:12:04.218963100Z",
     "start_time": "2023-12-10T02:12:04.079944900Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 划分训练集与测试集"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [],
   "source": [
    "categorical = ['gender','seniorcitizen','partner','dependents','phoneservice','multiplelines'\n",
    "               ,'internetservice','onlinesecurity','onlinebackup','deviceprotection','techsupport',\n",
    "               'streamingtv','streamingmovies','contract','paperlessbilling','paymentmethod']\n",
    "numerical = ['tenure','monthlycharges','totalcharges']"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:12:52.700542100Z",
     "start_time": "2023-12-10T02:12:52.675542400Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "outputs": [
    {
     "data": {
      "text/plain": "5634"
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "df_train_full,df_val =  train_test_split(df,test_size=0.2,random_state=11)\n",
    "len(df_train_full)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:50:59.546403400Z",
     "start_time": "2023-12-10T02:50:59.488600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 训练模型"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "outputs": [],
   "source": [
    "from sklearn.feature_extraction import DictVectorizer\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "def train(df,y,C=0.1):\n",
    "    cat = df[categorical+numerical].to_dict(orient='records') # 将df转化为字典形式\n",
    "    dv = DictVectorizer() # 创建字典向量化对象\n",
    "    dv.fit(cat) # 训练字典化向量对象\n",
    "    X = dv.transform(cat) # 生成数据\n",
    "    model = LogisticRegression(solver='liblinear',C=C)\n",
    "    model.fit(X,y)\n",
    "    return dv,model # 返回字典向量化对象与模型"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:57:04.074648700Z",
     "start_time": "2023-12-10T02:57:04.063637900Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 将模型应用到新数据"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "outputs": [],
   "source": [
    "def predict(df,dv,model):\n",
    "    cat = df[categorical+numerical].to_dict(orient='records')\n",
    "    X = dv.transform(cat) # 应用与训练中相同的独热编码\n",
    "    y_pred = model.predict_proba(X)[:,1] # 使用该模型进行预测\n",
    "    return y_pred # 返回值是正类的概率"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T02:57:05.842400200Z",
     "start_time": "2023-12-10T02:57:05.835402500Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## K折交叉验证"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.8517982059089787, 0.8358129159522889, 0.8203898514851484, 0.8381011176498885, 0.873774714797096, 0.858608656678192, 0.8325081128098759, 0.8335734409015239, 0.8440860215053764, 0.8457783918541436]\n",
      "auc=0.843,0.014\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import KFold # 导入KFold类\n",
    "from sklearn.metrics import roc_auc_score\n",
    "kfold = KFold(n_splits=10,shuffle=True,random_state=1) # 使用它将函数划分为10个部分\n",
    "aucs = [] # 创建一个用于存储结果的列表\n",
    "for train_idx,val_idx in kfold.split(df_train_full): # 迭代这10个不同的数据划分\n",
    "    df_train = df_train_full.iloc[train_idx]\n",
    "    df_val = df_train_full.iloc[val_idx] # 将数据集划分为训练集和验证集\n",
    "\n",
    "    y_train= df_train.churn.values\n",
    "    y_val = df_val.churn.values\n",
    "\n",
    "    dv,model = train(df_train,y_train)\n",
    "    y_pred = predict(df_val,dv,model) # 训练模型做出预测\n",
    "\n",
    "    auc = roc_auc_score(y_val,y_pred) # 使用AUC在验证集上评估模型的质量\n",
    "    aucs.append(auc) # 将auc结果保存到结果列表中\n",
    "\n",
    "print(aucs)\n",
    "print('auc=%0.3f,%0.3f'%(np.mean(aucs),np.std(aucs)))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T03:09:02.036656100Z",
     "start_time": "2023-12-10T03:08:58.817654600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 寻找最佳参数"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C=0.001,auc=0.823 0.015\n",
      "C=0.01,auc=0.840 0.012\n",
      "C=0.1,auc=0.844 0.012\n",
      "C=0.5,auc=0.844 0.012\n",
      "C=1,auc=0.844 0.012\n",
      "C=10,auc=0.844 0.012\n"
     ]
    }
   ],
   "source": [
    "nfolds = 5\n",
    "kfold = KFold(n_splits=nfolds,shuffle=True,random_state=1)\n",
    "for C in [0.001,0.01,0.1,0.5,1,10]:\n",
    "    aucs = []\n",
    "    for train_idx,val_idx in kfold.split(df_train_full):\n",
    "        df_train = df_train_full.iloc[train_idx]\n",
    "        df_val = df_train_full.iloc[val_idx]\n",
    "\n",
    "        y_train = df_train.churn.values\n",
    "        y_val = df_val.churn.values\n",
    "\n",
    "        dv,model = train(df_train,y_train,C=C)\n",
    "        y_pred = predict(df_val,dv,model)\n",
    "        auc = roc_auc_score(y_val,y_pred)\n",
    "        aucs.append(auc)\n",
    "\n",
    "    print('C=%s,auc=%0.3f %0.3f'%(C,np.mean(aucs),np.std(aucs)))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T03:13:11.022672500Z",
     "start_time": "2023-12-10T03:13:01.972694400Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 训练选好的模型"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.8495197192204674\n"
     ]
    }
   ],
   "source": [
    "y_train = df_train_full.churn.values\n",
    "y_test = df_val.churn.values\n",
    "dv,model = train(df_train_full,y_train,C=0.1) # 在完整的数据集上训练模型\n",
    "y_pred =predict(df_val,dv,model) # 应用于测试数据集\n",
    "auc = roc_auc_score(y_test,y_pred)\n",
    "print(auc)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-12-10T03:15:04.383466500Z",
     "start_time": "2023-12-10T03:15:04.016485300Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
